package util.util;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import util.util.error.BizException;
import util.util.error.JsonReturnCode;

import java.io.*;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class DevFileUtil {

    public static final String rootPath = "D:\\20project\\SSH2.0\\S00040\\bidding\\yuanmao-bidding\\golden-bd-app\\src\\main\\java\\";

    /**
     * 读取 Excel -> workbook
     *
     * @param path
     * @return
     */
    public static Workbook getWorkbook(String path) {
        Workbook wb = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                return createWorkbook(path);
            }
            FileInputStream fis = new FileInputStream(file);
            if (path.endsWith("xls")) {
                wb = new HSSFWorkbook(fis);
            } else if (path.endsWith("xlsx")) {
                wb = new XSSFWorkbook(fis);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.FILE_EXCEL_READ.addParam("msg", path));
        }
        return wb;
    }

    /**
     * 创建  workbook
     *
     * @param path 路径，提取格式用
     * @return
     */
    public static Workbook createWorkbook(String path) {
        Workbook wb = null;
        try {
            if (path.endsWith("xls")) {
                wb = new HSSFWorkbook();
            } else if (path.endsWith("xlsx")) {
                wb = new XSSFWorkbook();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.FILE_EXCEL_GET.addParam("msg", path));
        }
        return wb;
    }

    /**
     * 创建 workbook -> 文件
     *
     * @param workbook   代码
     * @param createPath 路径 + 名称
     */
    public static void createExcle(Workbook workbook, String createPath) {
        try {
            //生成文件
            File file = new File(createPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            file.createNewFile();
            OutputStream os = new FileOutputStream(file);
            workbook.write(os);
            os.flush();
            os.close();
            System.out.println(createPath + "  生成。");
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.FILE_EXCEL_CREAT.addParam("msg", createPath));
        }
    }

    /**
     * 读取  Excel -> sheet
     *
     * @param path
     * @param sheetPage
     * @return
     */
    public static Sheet getSheet(String path, int sheetPage) {
        Sheet sheet = null;
        try {
            Workbook wb = getWorkbook(path);
            if (wb != null) {
                //获取第一个表单sheet
                sheet = wb.getSheetAt(sheetPage);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.FILE_SHEET_CREAT.addParam("msg", path));
        }
        return sheet;
    }

    /**
     * 读取  Excel -> sheet
     *
     * @param path
     * @return
     */
    public static int getSheetNumbers(String path) {
        int numberOfSheets = 0;
        try {
            Workbook wb = getWorkbook(path);
            if (wb != null) {
                //获取第一个表单sheet
                numberOfSheets = wb.getNumberOfSheets();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return numberOfSheets;
    }

    /**
     * 读取Excel  row -> String
     *
     * @param row 行
     * @param i   单元格
     */
    public static String getCellValue(Row row, int i) {
        return getCellValue(row, i, "");
    }

    /**
     * 读取Excel  row -> String
     *
     * @param row 行
     * @param i   单元格
     */
    public static <T> T getCellValueObject(Row row, int i) {
        return (T) getCellValue(row, i, "");
    }

    /**
     * 读取Excel  row -> String
     *
     * @param row 行
     * @param i   单元格
     */
    public static String getCellValueNull(Row row, int i) {
        return getCellValue(row, i, null);
    }

    /**
     * 读取Excel  row -> String
     *
     * @param row          行
     * @param i            单元格
     * @param defaultValue 默认值
     */
    public static String getCellValue(Row row, int i, String defaultValue) {
        if (!DevComUtil.isEmpty(row)) {
            Cell cell = row.getCell(i);
            if (!DevComUtil.isEmpty(cell)) {
                CellType cellTypeEnum = cell.getCellTypeEnum();
                if (cellTypeEnum == CellType.NUMERIC) {
                    // 数字
                    NumberFormat nf = NumberFormat.getInstance();
                    // 去掉逗号
                    nf.setGroupingUsed(false);
                    String s = nf.format(cell.getNumericCellValue());
                    return s;
                }
                if (cellTypeEnum == CellType.FORMULA) {
                    // 公式
//                    double numericCellValue = cell.getNumericCellValue();
//                    return String.valueOf(numericCellValue);
                    String stringCellValue = cell.toString();
//                    DecimalFormat df = new DecimalFormat("0.00");
                    return stringCellValue;
                }
                // 字符串
                return cell.getStringCellValue().trim();
            }
        }
        return defaultValue;
    }

    /**
     * 读取文件内容
     *
     * @param filePath String 如 c:\\1.txt 绝对路径
     * @return boolean
     */
    public static String readFileNote2(String filePath) {
        StringBuilder sb = new StringBuilder();
        try {
            File f = new File(filePath);
            if (f.isFile() && f.exists()) {
                InputStreamReader read = new InputStreamReader(new FileInputStream(f), "UTF-8");
                BufferedReader reader = new BufferedReader(read);
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                    sb.append("\n");
                }
                read.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.FILE_NOTE_CREAT.addParam("msg", filePath));
        }
        return sb.toString();
    }

    /**
     * 创建  String -> 文件
     *
     * @param pageStr    代码
     * @param createPath 路径 + 名称
     */
    public static void createFile(String pageStr, String createPath) {
        try {
            //生成文件
            File file = new File(createPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            file.createNewFile();
            OutputStream os = new FileOutputStream(file);
            os.write(pageStr.getBytes());
            os.flush();
            os.close();
            System.out.println(createPath + "  生成。");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("生成文件页面出错！");
        }
    }


    /**
     * 创建  String -> 文件
     *
     * @param pageStr    代码
     * @param createPath 路径 + 名称
     */
    public static void createFile(List<String> pageStr, String createPath) {

        StringBuilder sb = new StringBuilder(pageStr.size() * 40);
        for (String s : pageStr) {
            sb.append(s);
            sb.append("\n");
        }
        createFile(sb.toString(), createPath);
    }

    /**
     * 获取某目录下所有的文件
     *
     * @param rootPath 根目录
     * @return 文件集合
     */
    public static List<File> getFileList(String[] rootPath) {
        try {
            List<File> fileList = new ArrayList<>();
            for (String path : rootPath) {
                File file = new File(path);
                addFileList(file, fileList);
            }

            return fileList;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("目录不对啊。。。。");
        }
    }

    /**
     * 获取某目录下所有的文件
     *
     * @param rootPath 根目录
     * @return 文件集合
     */
    public static List<File> getFileList(String rootPath) {
        try {
            List<File> fileList = new ArrayList<>();
            File file = new File(rootPath);
            addFileList(file, fileList);
            return fileList;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("目录不对啊。。。。");
        }
    }

    /**
     * 递归遍历目录
     *
     * @param file     目录
     * @param fileList 文件集合
     */
    private static void addFileList(File file, List<File> fileList) {
        if (file == null) {
            return;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (!DevComUtil.isEmpty(files)) {
                for (File fi : files) {
                    addFileList(fi, fileList);
                }
            }
        } else {
            fileList.add(file);
        }
    }

    /**
     * 复制文件夹 （默认文件名称不修改）
     *
     * @param source 源文件夹
     * @param dest   目标文件夹
     */
    public static void copyFileList(String source, String dest) {
        copyFileList(source, dest, null);
    }

    /**
     * 复制文件夹
     *
     * @param source     源文件夹
     * @param dest       目标文件夹
     * @param changeName 文件名称修改规则
     */
    public static void copyFileList(String source, String dest, Function<String, String> changeName) {
        File oldFile = new File(source);
        File newFile = new File(dest);
        if (!newFile.exists() && !newFile.mkdirs()) {
            System.out.println("失败：" + dest);
            return;
        }
        File[] files = oldFile.listFiles();

        if (!DevComUtil.isEmpty(files)) {
            for (File file : files) {
                String name = file.getName();
                String newName = changeName == null ? name : changeName.apply(name);
                copyFile(source + "\\" + name, dest + "\\" + newName);
            }
        }
    }


    /**
     * 复制文件夹
     *
     * @param source     源文件夹
     * @param dest       目标文件夹
     * @param changeName 文件名称修改规则
     */
    public static void copyAllFileList(String source, String dest, Function<String, String> changeName) {
        List<File> fileList = getFileList(source);
        if (!DevComUtil.isEmpty(fileList)) {
            for (File file : fileList) {
                String name = file.getName();
                String newName = changeName == null ? name : changeName.apply(name);
                String newPath = file.getParent().replace(source, dest);
                File newFile = new File(newPath);
                if (!newFile.exists() && !newFile.mkdirs()) {
                    System.out.println("失败：" + dest);
                    return;
                }
                copyFile(file.getAbsolutePath(), newPath + "\\" + newName);
            }
        }
    }

    /**
     * 复制文件
     *
     * @param source 源文件
     * @param dest   目标文件
     */
    public static void copyFile(String source, String dest) {
        File newFile = new File(dest);
        File parentFile = newFile.getParentFile();
        if (!parentFile.exists() && !parentFile.mkdirs()) {
            System.out.println("失败：" + dest);
            return;
        }
        try (InputStream input = new BufferedInputStream(new FileInputStream(new File(source)));
             OutputStream output = new BufferedOutputStream(new FileOutputStream(new File(dest)))) {

            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, bytesRead);
            }
            System.out.println("复制成功：" + dest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
